﻿using System;
using System.Runtime.InteropServices;

namespace Ast.Core.WinApi.DbgHelp
{
    public class DbgHelpStructure
    {
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct SymbolInfo
        {
            public uint SizeOfStruct;
            public uint TypeIndex;
            public ulong Reserved1;
            public ulong Reserved2;
            public uint Index;
            public uint Size;
            public ulong ModBase;
            public DbgHelpConstant.SymFlag Flags;
            public ulong Value;
            public ulong Address;
            public uint Register;
            public uint Scope;
            public DbgHelpConstant.SymTagEnum Tag;
            public int NameLen;
            public int MaxNameLen;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]
            public string Name;

            public static SymbolInfo Create()
            {
                return new SymbolInfo {SizeOfStruct = 88, MaxNameLen = 1024};
            }
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct ImagehlpModule64
        {
            public uint SizeOfStruct;
            public ulong BaseOfImage;
            public uint ImageSize;
            public uint TimeDateStamp;
            public uint CheckSum;
            public uint NumSyms;
            public DbgHelpConstant.SymType SymType;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string ModuleName;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
            public string ImageName;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
            public string LoadedImageName;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
            public string LoadedPdbName;

            public uint CVSig;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260*3)]
            public string CVData;

            public uint PdbSig;
            public Guid PdbSig70;
            public uint PdbAge;
            public bool PdbUnmatched;
            public bool DbgUnmatched;
            public bool LineNumbers;
            public bool GlobalSymbols;
            public bool TypeInfo;
            public bool SourceIndexed;
            public bool Publics;
            public int MachineType;
            public int Reserved;

            public static ImagehlpModule64 Create()
            {
                return new ImagehlpModule64 {SizeOfStruct = (uint) Marshal.SizeOf<ImagehlpModule64>()};
            }
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct ImagehlpDeferredSymbolLoad64
        {
            public int SizeOfStruct;
            public long BaseOfImage;
            public int CheckSum;
            public int TimeDateStamp;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string FileName;

            public bool Reparse;
            public IntPtr hFile;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct ImagehlpStackFrame
        {
            public ulong InstructionOffset;
            public ulong ReturnOffset;
            public ulong FrameOffset;
            public ulong StackOffset;
            public ulong BackingStoreOffset;
            public ulong FuncTableEntry;

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public ulong[] Params;

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
            public ulong[] Reserved;

            public bool Virtual;
            public uint Reserved2;
        }
    }
}